<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    html,body{margin: 0;padding: 0;}
    .cvs{display:block;}
  </style>
</head>
<body>
  <canvas class="cvs"></canvas>
</body>
<script>

  const cvs = document.querySelector(".cvs");
  cvs.width = window.innerWidth;
  cvs.height = window.innerHeight;
  const ctx = cvs.getContext("2d");

  // 我的飞机，一个，单例
  const myPlane = {
    init({src, x, y}){
      this.src=  src;
      this.x = x;
      this.y = y;

      const that = this;
      // 绘制我的飞机图片
      this.img = drawImg({
        src:this.src,
        x:this.x,
        y:this.y,
        cb:function({ w, h }){
          that.w = w;
          that.h = h;
        }
      });

      this.addEvent();
    },
    addEvent(){
      const that = this;
      // 鼠标移动时我的飞机跟随
      cvs.addEventListener("mousemove", function(eve){
        const e = eve || window.event;
        // 先清除上次绘制
        ctx.clearRect(that.x, that.y, that.w, that.h);
        // 重绘我的飞机位置
        ctx.drawImage(that.img, e.offsetX - that.w/2, e.offsetY - that.h/2, that.w, that.h);
        // 将本次位置记录下来，以便下次清除
        that.x = e.offsetX - that.w/2;
        that.y = e.offsetY - that.h/2;
      })
      cvs.addEventListener("click", function(){
        // 创建子弹
        new Bullet({
          x: that.x + that.w/2,
          y: that.y,
          src:"./images/bullet.png",
          speedY:10
        });
      })
    }
  }

  // 子弹，多个，工厂
  class Bullet{
    constructor({ x, y, src, speedY }){
      this.x = x;
      this.y = y;
      this.src = src;
      this.speedY = speedY;

      this.init();
    }
    init(){
      const that = this;
      this.img = drawImg({
        src:this.src,
        x:this.x,
        y:this.y,
        cb:function({ w, h }){
          that.w = w;
          that.h = h;
          that.move();
        }
      });
    }
    move(){
      setInterval(()=>{
        // 清除之前
        ctx.clearRect(this.x, this.y, this.w, this.h);
        // 在新的位置重新绘制
        ctx.drawImage(this.img, this.x, this.y-=this.speedY);
      }, 100);
    }
  }

  // 敌机，多个，工厂
  class Enemy{
    constructor({ src, type }){
      this.type = type;
      this.x = random(0, cvs.width);
      this.y = 0;
      switch(this.type){
        case 1:
          this.src = "./images/plane1.png";
          this.time = 15;
          break;
        case 2:
          this.src = "./images/plane2.png";
          this.time = 40;
          break;
        case 3:
          this.src = "./images/plane3.png";
          this.time = 100;
          break;
      }

      this.init();
    }
    init(){
      const that = this;
      this.img = drawImg({
        src: this.src,
        x: this.x,
        y: this.y,
        cb:function({ w, h }){
          that.w = w;
          that.h = h;
          that.move();
        }
      });
    }
    move(){
      setInterval(()=>{
        ctx.clearRect(this.x, this.y, this.w, this.h);
        ctx.drawImage(this.img, this.x, this.y+=1);
      }, this.time);
    }
  }

  myPlane.init({
    src:"./images/me.png",
    x:100,
    y:300
  })

  new Enemy({
    type: 1
  })
  new Enemy({
    type: 2
  })
  new Enemy({
    type: 3
  })
  
  




  function drawImg({ src, x, y, cb }){
    const img = new Image();
    img.src = src;
    img.onload = function(){
      ctx.drawImage(this, x, y, this.width, this.height);
      cb({
        w:this.width,
        h:this.height
      });
    }
    return img;
  }
  

  function random(a,b){
    return Math.round(Math.random()*(a-b)+b);
  }
</script>
</html>